package org.cytoscape.myapp.cytoscape_app_v1.internal.UI;

import java.awt.Color;
import java.awt.Component;
import java.awt.GridLayout;
import java.util.List;
import java.util.Set;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;


import javax.swing.GroupLayout;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.GroupLayout.Alignment;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;


import org.cytoscape.application.CyApplicationManager;
import org.cytoscape.application.events.SetCurrentNetworkEvent;
import org.cytoscape.application.events.SetCurrentNetworkListener;
import org.cytoscape.application.swing.CytoPanelComponent;
import org.cytoscape.application.swing.CytoPanelName;
import org.cytoscape.event.CyEventHelper;
import org.cytoscape.group.CyGroupManager;
import org.cytoscape.model.CyNetwork;
import org.cytoscape.myapp.cytoscape_app_v1.internal.UI.Constants.Priority;
import org.cytoscape.myapp.cytoscape_app_v1.internal.model.NetworkSettings;
import org.cytoscape.myapp.cytoscape_app_v1.internal.model.StateExpanded;
import org.cytoscape.myapp.cytoscape_app_v1.internal.model.UtilNetworkManager;
import org.cytoscape.myapp.cytoscape_app_v1.internal.tasks.groups.GroupCollapsedExpandTask;
import org.cytoscape.myapp.cytoscape_app_v1.internal.tasks.groups.GroupsRemoveTask;
import org.cytoscape.work.TaskIterator;
import org.cytoscape.work.TaskManager;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JScrollPane;
import javax.swing.AbstractAction;
import javax.swing.Action;



public class CytoPanel extends JPanel implements CytoPanelComponent, SetCurrentNetworkListener {


	private static final long serialVersionUID = 1L;

	private final String Title = "Social Analizer";
    
	private final CyApplicationManager applicationManager;
	private final CyGroupManager groupManager;
	private final TaskManager<?, ?> taskManager;
	private CyEventHelper eventHelper;	
	
	private UtilNetworkManager utilNetworkManager;
	
	
	private JPanel panelGroupsSimple;
	private JComboBox<String> comboBoxGroupsSimple;
	private JButton btnButtonRunSimple;
	private JPanel panelGroupsComplex;
	private JPanel panelOptions;
	private JButton btnColapsedExpandButton;
	private JButton buttonRemoveAllGroups;
	private JScrollPane scrollPaneCriterios;
	private JPanel criteriosPanel;
	
	private JComboBox<String> comboBoxAttributeComplex;
	private JButton btnButtonRunComplex;
	private JComboBox<Priority> comboPriority;
	
	private ComboSimpleItemListener item = new ComboSimpleItemListener();
	private ComboComplexItemListener itemComplex = new ComboComplexItemListener();
	private ComboPriorityItemListener itemPriority = new ComboPriorityItemListener();
    
	/*
     * 
     */
	private Long currentNetworkSUID;
	private JButton btnLayoutOptions;
	private final Action action = new SwingAction();
	
	public Long getCurrentNetworkSUID() {
		return currentNetworkSUID;
	}

	public void setCurrentNetworkSUID(Long currentNetworkSUID) {
		this.currentNetworkSUID = currentNetworkSUID;
	}
    
    public CytoPanel(CyApplicationManager nmg, 
					CyGroupManager groupManager,
					@SuppressWarnings("rawtypes") TaskManager taskManager, 
					UtilNetworkManager utilNetworkManager, 
					CyEventHelper eventHelper){
    	
    	this.applicationManager = nmg;
    	this.groupManager = groupManager;
    	this.taskManager = taskManager;
    	this.utilNetworkManager = utilNetworkManager;
    	this.eventHelper = eventHelper;
    	
    	this.initUserInterface();
    	
    	CyNetwork network = applicationManager.getCurrentNetwork();
    	
		if (network != null) {
			this.currentNetworkSUID = network.getSUID();
			
			this.utilNetworkManager.addNetworkSettings(network);
						
			updateUserInterface();
			disableUserInterface(true);
		
		} else {
			disableUserInterface(false);
		}
    }
    
    private void updateUserInterface(){
    	
    	/*
    	 * Elimino lista viejas y Cargo Listas desplagables de la red actual 
    	 */
    	NetworkSettings netSettings = utilNetworkManager.getCurrrentNetworkSettings(currentNetworkSUID);
    	
    	comboBoxGroupsSimple.removeItemListener(item);
    	comboBoxGroupsSimple.removeAllItems();
    	Set<String> columnsSimple = netSettings.getColumnNamesSimple();
    	for(String columnS:columnsSimple){
    		comboBoxGroupsSimple.addItem(columnS);
    		
    	}
    	comboBoxGroupsSimple.setSelectedIndex(netSettings.getSelectedSimpleColumn());
    	comboBoxGroupsSimple.addItemListener(item);
    	
    	comboBoxAttributeComplex.removeItemListener(itemComplex);
    	comboBoxAttributeComplex.removeAllItems();
    	Set<String> columnsComplex = netSettings.getColumnNamesGroups();
    	for(String columnC:columnsComplex){
    		comboBoxAttributeComplex.addItem(columnC);
    		
    	}
    	comboBoxAttributeComplex.setSelectedIndex(netSettings.getSelectedGroupsColumn());
    	comboBoxAttributeComplex.addItemListener(itemComplex);
    	
    	comboPriority.setSelectedIndex(netSettings.getSelectedPriority());
    	
    	criteriosPanel.removeAll();
    	List<Component> components= netSettings.getCriteriaComponents();
    	for(Component comp:components){
    		criteriosPanel.add(comp);
    		panelGroupsComplex.validate();
    		panelGroupsComplex.repaint();

    	}
    	
 
    }
    
    private void disableUserInterface(boolean enable) {
    	comboBoxGroupsSimple.setEnabled(enable);
    	comboBoxAttributeComplex.setEnabled(enable);
    	comboPriority.setEnabled(enable);
    	btnButtonRunSimple.setEnabled(enable);
	
	}
    
   
    private void initUserInterface(){
    
    	
    	setBorder(new LineBorder(new Color(255, 255, 255), 1, true));
		
		panelGroupsSimple = new JPanel();
		panelGroupsSimple.setBorder(new TitledBorder(null, "Simples  Groups", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		
		comboBoxGroupsSimple = new JComboBox<String>();
		comboBoxGroupsSimple.addItemListener(item);
		btnButtonRunSimple = new JButton("Run");
		btnButtonRunSimple.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				NetworkSettings networkSettings = utilNetworkManager.getCurrrentNetworkSettings(currentNetworkSUID);
				taskManager.execute(networkSettings.getTaskIteratorSimple());
				networkSettings.setState();
			}
		});
		
		JLabel lblTarget = new JLabel("Target");
				
		
		GroupLayout gl_panelGroupsSimple = new GroupLayout(panelGroupsSimple);
		gl_panelGroupsSimple.setHorizontalGroup(
			gl_panelGroupsSimple.createParallelGroup(Alignment.LEADING)
				.addGroup(gl_panelGroupsSimple.createSequentialGroup()
					.addComponent(lblTarget)
					.addGap(14)
					.addComponent(comboBoxGroupsSimple, GroupLayout.PREFERRED_SIZE, 133, GroupLayout.PREFERRED_SIZE)
					.addPreferredGap(ComponentPlacement.RELATED, 101, Short.MAX_VALUE)
					.addComponent(btnButtonRunSimple, GroupLayout.PREFERRED_SIZE, 70, GroupLayout.PREFERRED_SIZE)
					.addGap(18))
		);
		gl_panelGroupsSimple.setVerticalGroup(
			gl_panelGroupsSimple.createParallelGroup(Alignment.LEADING)
				.addGroup(gl_panelGroupsSimple.createSequentialGroup()
					.addContainerGap()
					.addGroup(gl_panelGroupsSimple.createParallelGroup(Alignment.BASELINE)
						.addComponent(comboBoxGroupsSimple, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
						.addComponent(lblTarget)
						.addComponent(btnButtonRunSimple))
					.addContainerGap(12, Short.MAX_VALUE))
		);
		panelGroupsSimple.setLayout(gl_panelGroupsSimple);
		
		
		criteriosPanel = new JPanel(new GridLayout(0,1));
		criteriosPanel.setBorder(null);
		
		
		scrollPaneCriterios = new JScrollPane(criteriosPanel);
		scrollPaneCriterios.setToolTipText("");
		scrollPaneCriterios.setViewportBorder(new TitledBorder(null, "Criterios", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		scrollPaneCriterios.setAlignmentY(LEFT_ALIGNMENT);
		
		panelGroupsComplex = new JPanel();
		panelGroupsComplex.setBorder(new TitledBorder(null, "Complex Groups", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		
		JButton btnAddCriterioButton = new JButton("Add");
		
		btnAddCriterioButton.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				
				NetworkSettings ns = utilNetworkManager.getCurrrentNetworkSettings(currentNetworkSUID);
				
				criteriosPanel.add(new SubComponent(criteriosPanel, ns));
				panelGroupsComplex.validate();
				panelGroupsComplex.repaint();
				panelGroupsComplex.setVisible(true);
			}
		});

		
		comboBoxAttributeComplex = new JComboBox<String>();
		comboBoxAttributeComplex.addItemListener(itemComplex);
		
		JLabel label = new JLabel("Target");
		
		btnButtonRunComplex = new JButton("Run");
		btnButtonRunComplex.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				NetworkSettings networkSettings = utilNetworkManager.getCurrrentNetworkSettings(currentNetworkSUID);
				taskManager.execute(networkSettings.getTaskIteratorGroup());
				networkSettings.setState();
			}
		});
		
		this.comboPriority = new JComboBox<Priority>();
		this.comboPriority.addItem(Constants.Priority.Xor);
		this.comboPriority.addItem(Constants.Priority.XorBest);
		this.comboPriority.addItem(Constants.Priority.OR);
		this.comboPriority.addItemListener(itemPriority);
		
		
		JLabel lblPriority = new JLabel("Priority");
		
		JButton btnNewButton = new JButton("Show/Hide Edges");
		btnNewButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				NetworkSettings networkSettings = utilNetworkManager.getCurrrentNetworkSettings(currentNetworkSUID);
				taskManager.execute(networkSettings.getTaskIteratorVirtualEdge());
				networkSettings.changeStateVirtualEdge();
				eventHelper.flushPayloadEvents();

			
				
			}
		});
		
		
		GroupLayout gl_panelGroupsComplex = new GroupLayout(panelGroupsComplex);
		gl_panelGroupsComplex.setHorizontalGroup(
			gl_panelGroupsComplex.createParallelGroup(Alignment.TRAILING)
				.addGroup(gl_panelGroupsComplex.createSequentialGroup()
					.addGap(4)
					.addComponent(label, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
					.addPreferredGap(ComponentPlacement.UNRELATED)
					.addComponent(comboBoxAttributeComplex, GroupLayout.PREFERRED_SIZE, 133, GroupLayout.PREFERRED_SIZE)
					.addPreferredGap(ComponentPlacement.RELATED)
					.addComponent(lblPriority, GroupLayout.DEFAULT_SIZE, 34, Short.MAX_VALUE)
					.addPreferredGap(ComponentPlacement.RELATED)
					.addComponent(comboPriority, GroupLayout.PREFERRED_SIZE, 133, GroupLayout.PREFERRED_SIZE)
					.addGap(51))
				.addGroup(gl_panelGroupsComplex.createSequentialGroup()
					.addContainerGap()
					.addComponent(btnNewButton)
					.addPreferredGap(ComponentPlacement.RELATED, 142, Short.MAX_VALUE)
					.addComponent(btnButtonRunComplex, GroupLayout.PREFERRED_SIZE, 71, GroupLayout.PREFERRED_SIZE)
					.addGap(67))
				.addGroup(gl_panelGroupsComplex.createSequentialGroup()
					.addContainerGap(296, Short.MAX_VALUE)
					.addComponent(btnAddCriterioButton)
					.addGap(58))
				.addGroup(Alignment.LEADING, gl_panelGroupsComplex.createSequentialGroup()
					.addComponent(scrollPaneCriterios, GroupLayout.PREFERRED_SIZE, 389, GroupLayout.PREFERRED_SIZE)
					.addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
		);
		gl_panelGroupsComplex.setVerticalGroup(
			gl_panelGroupsComplex.createParallelGroup(Alignment.LEADING)
				.addGroup(gl_panelGroupsComplex.createSequentialGroup()
					.addGroup(gl_panelGroupsComplex.createParallelGroup(Alignment.BASELINE)
						.addComponent(label)
						.addComponent(comboBoxAttributeComplex, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
						.addComponent(lblPriority)
						.addComponent(comboPriority, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
					.addPreferredGap(ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
					.addComponent(btnAddCriterioButton)
					.addPreferredGap(ComponentPlacement.RELATED)
					.addComponent(scrollPaneCriterios, GroupLayout.PREFERRED_SIZE, 224, GroupLayout.PREFERRED_SIZE)
					.addGap(7)
					.addGroup(gl_panelGroupsComplex.createParallelGroup(Alignment.BASELINE)
						.addComponent(btnButtonRunComplex)
						.addComponent(btnNewButton))
					.addContainerGap())
		);
		panelGroupsComplex.setLayout(gl_panelGroupsComplex);
		
		
		panelOptions = new JPanel();
		panelOptions.setBorder(new TitledBorder(null, "Groups Options", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		
		btnColapsedExpandButton = new JButton("Expand/Collaps");
		btnColapsedExpandButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				NetworkSettings networkSettings = utilNetworkManager.getCurrrentNetworkSettings(currentNetworkSUID);
				GroupCollapsedExpandTask task = new GroupCollapsedExpandTask(applicationManager, groupManager, networkSettings.getState());
				networkSettings.setState();
				taskManager.execute(new TaskIterator(task));
				eventHelper.flushPayloadEvents();
			}
		
		});
		
		buttonRemoveAllGroups = new JButton("Remove All");
		buttonRemoveAllGroups.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				NetworkSettings networkSettings = utilNetworkManager.getCurrrentNetworkSettings(currentNetworkSUID);
				GroupsRemoveTask task = new GroupsRemoveTask(applicationManager, groupManager);
				taskManager.execute(new TaskIterator(task));
				networkSettings.setFirstState(new StateExpanded(applicationManager));
			}
		});
		
		btnLayoutOptions = new JButton("Layout Options");
		btnLayoutOptions.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				JFrame a = new VisualLayoutOption(utilNetworkManager.getCurrrentNetworkSettings(currentNetworkSUID),taskManager,eventHelper);
				a.setVisible(true);
			}
		});
		btnLayoutOptions.setAction(action);
		GroupLayout gl_panelOptions = new GroupLayout(panelOptions);
		gl_panelOptions.setHorizontalGroup(
			gl_panelOptions.createParallelGroup(Alignment.LEADING)
				.addGroup(gl_panelOptions.createSequentialGroup()
					.addContainerGap()
					.addComponent(btnColapsedExpandButton)
					.addPreferredGap(ComponentPlacement.RELATED)
					.addComponent(buttonRemoveAllGroups)
					.addPreferredGap(ComponentPlacement.RELATED)
					.addComponent(btnLayoutOptions)
					.addGap(49))
		);
		gl_panelOptions.setVerticalGroup(
			gl_panelOptions.createParallelGroup(Alignment.LEADING)
				.addGroup(gl_panelOptions.createSequentialGroup()
					.addContainerGap()
					.addGroup(gl_panelOptions.createParallelGroup(Alignment.BASELINE)
						.addComponent(btnColapsedExpandButton)
						.addComponent(buttonRemoveAllGroups)
						.addComponent(btnLayoutOptions))
					.addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
		);
		panelOptions.setLayout(gl_panelOptions);
		GroupLayout groupLayout = new GroupLayout(this);
		groupLayout.setHorizontalGroup(
			groupLayout.createParallelGroup(Alignment.LEADING)
				.addGroup(groupLayout.createSequentialGroup()
					.addGroup(groupLayout.createParallelGroup(Alignment.TRAILING, false)
						.addComponent(panelOptions, Alignment.LEADING, 0, 0, Short.MAX_VALUE)
						.addGroup(Alignment.LEADING, groupLayout.createParallelGroup(Alignment.TRAILING, false)
							.addComponent(panelGroupsSimple, Alignment.LEADING, 0, 0, Short.MAX_VALUE)
							.addComponent(panelGroupsComplex, Alignment.LEADING, GroupLayout.PREFERRED_SIZE, 380, Short.MAX_VALUE)))
					.addContainerGap(27, Short.MAX_VALUE))
		);
		groupLayout.setVerticalGroup(
			groupLayout.createParallelGroup(Alignment.LEADING)
				.addGroup(groupLayout.createSequentialGroup()
					.addComponent(panelGroupsSimple, GroupLayout.PREFERRED_SIZE, 69, GroupLayout.PREFERRED_SIZE)
					.addPreferredGap(ComponentPlacement.RELATED)
					.addComponent(panelGroupsComplex, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
					.addGap(1)
					.addComponent(panelOptions, GroupLayout.PREFERRED_SIZE, 68, GroupLayout.PREFERRED_SIZE)
					.addGap(43))
		);
		setLayout(groupLayout);
    }
    
    @Override
    public CytoPanelName getCytoPanelName() {
        return CytoPanelName.WEST;
    }
        
	@Override
	public Component getComponent() {
		return this; 
	}

	@Override
	public Icon getIcon() {
		return null;
	}

	@Override
	public String getTitle() {
		return Title;
	}


	@Override
	public void handleEvent(final SetCurrentNetworkEvent e) {
		
		System.out.println("Network selection changed event, source: " + e.getSource());
		
		SwingUtilities.invokeLater(new Runnable() {
			@Override
			public void run() {
				try {
					System.out.println("pufsdfds");
					Thread.sleep(100);
				} catch (InterruptedException e1) {
					e1.printStackTrace();
				}
				CyNetwork currentNetwork = e.getNetwork();
				if (currentNetwork != null) {
					currentNetworkSUID = currentNetwork.getSUID();
					if (!utilNetworkManager.existsNetworkSettings(currentNetworkSUID)) {
						utilNetworkManager.addNetworkSettings(currentNetwork);
					}
					disableUserInterface(true);
					
					updateUserInterface();

				}
			}
		});
		
	}
	
	class ComboSimpleItemListener implements ItemListener{
		
		public void itemStateChanged(ItemEvent e) {
			@SuppressWarnings("unchecked")
			JComboBox<String> cb = (JComboBox<String>)e.getSource();
			if (e.getStateChange() == ItemEvent.SELECTED ){ 
				NetworkSettings ns =utilNetworkManager.getCurrrentNetworkSettings(currentNetworkSUID); 
				int petIndex = (int)cb.getSelectedIndex(); 
				ns.setSelectedSimpleColumn(petIndex); 
				} 
			}
	}
	
	class ComboComplexItemListener implements ItemListener{
		
		public void itemStateChanged(ItemEvent e) {
			@SuppressWarnings("unchecked")
			JComboBox<String> cb = (JComboBox<String>)e.getSource();
			if (e.getStateChange() == ItemEvent.SELECTED ){ 
				NetworkSettings ns =utilNetworkManager.getCurrrentNetworkSettings(currentNetworkSUID); 
				int petIndex = (int)cb.getSelectedIndex(); 
				ns.setSelectedGroupsColumn(petIndex); 
				} 
			}
	}
	
	class ComboPriorityItemListener implements ItemListener{
		
		public void itemStateChanged(ItemEvent e) {
			@SuppressWarnings("unchecked")
			JComboBox<String> cb = (JComboBox<String>)e.getSource();
			if (e.getStateChange() == ItemEvent.SELECTED ){ 
				NetworkSettings ns = utilNetworkManager.getCurrrentNetworkSettings(currentNetworkSUID); 
				int petIndex = (int)cb.getSelectedIndex(); 
				ns.setSelectedPriority(petIndex); 
				} 
			}
	}
	@SuppressWarnings("serial")
	private class SwingAction extends AbstractAction {
		public SwingAction() {
			putValue(NAME, "Layout Options");
			putValue(SHORT_DESCRIPTION, "Some short description");
		}
		public void actionPerformed(ActionEvent e) {
		}
	}
}
	
